﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FunctionalCLR.Core.Function;

namespace FunctionalCLR.Core {
    public class UserDefinedFunctionParser {

        private IParserFactory pf;

        private IUserDefinedFunctionFactory udfFactory;

        public UserDefinedFunctionParser(IParserFactory pf)
            : this(pf, new DefaultUserDefinedFunctionFactory()) {
        }

        public UserDefinedFunctionParser(
            IParserFactory pf, IUserDefinedFunctionFactory udfFactory) {
            this.pf = pf;
            this.udfFactory = udfFactory;
        }

        public UserDefinedFunctionNode Parse(string input) {
            string name = string.Empty;
            string funcBody = string.Empty;

            List<string> parameters = new List<string>();
            Lexer lexer = new Lexer(input);
            name = lexer.NextToken(TokenType.Identifier).Value;
            string comment = lexer.LastComment;
            Token token = lexer.NextToken(TokenType.LeftBrace);
            while (lexer.HasMoreTokens()) {
                token = lexer.NextToken(TokenType.Identifier);
                parameters.Add(token.Value);
                token = lexer.NextToken(TokenType.Comma, TokenType.RightBrace);
                if (token.TokenType == TokenType.RightBrace) {
                    break;
                }
            }
            lexer.NextToken(TokenType.Declare);
            while (lexer.HasMoreTokens()) {
                token = lexer.NextToken();
                funcBody = funcBody + token.Value;
            }
            parameters.Reverse();
            UserDefinedFunctionNode udf
                = this.udfFactory.Create();
            udf.Name = name;
            udf.Comment = lexer.LastComment;
            udf.Parameters = parameters.ToArray();
            udf.FuncBody = funcBody;
            //udf.Context = this.Context;
            udf.ParserFactory = pf;

            return udf;
        }
    }
}
